package com.psam;

import java.io.IOException;

import android.app.Activity;
import android.content.Context;
import android.jb.psam.PsamController;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import com.example.ht380d4G_jar_demo.R;

public class PSamActivity extends Activity {

	private static final byte[] createRandomCom = new byte[] { 0x00,
			(byte) 0x84, 0x00, 0x00, 0x04 };// 产生随机数指令
	private static final byte[] fileExitsCom = new byte[] { 0x00, (byte) 0xA4,
			0X00, 0X00, 0X02, 0X3F, 0x00 };// 检测是否已存在MF文件指令
	private static final byte[] createFileCom = new byte[] { (byte) 0x80,
			(byte) 0xe0, 0x3f, 0x00, 0x0d, 0x38, (byte) 0xff, (byte) 0xff,
			(byte) 0xf0, (byte) 0xf0, (byte) 0xff, (byte) 0xff, (byte) 0xff,
			(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff };// 产生MF文件指令
	private Button psam_reset_btn , psam_change_btn;

	private static final int TONE_RELATIVE_VOLUME = 80;
	private static final int TONE_LENGTH_MS = 150;// 延迟时间
	private boolean mDTMFToneEnabled;// 按键操作音
	private Object mToneGeneratorLock = new Object();// 监视器对象锁
	private ToneGenerator mToneGenerator;
	private EditText cosEt;
	private TextView noticeTv;
	private Spinner samNumSp, psam_sam_type_sp;
	private PsamController pSamCon;
	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 0:
				if (noticeTv != null)
					noticeTv.setText(msg.arg1 == 0 ? getString(R.string.reset_success)
							: getString(R.string.reset_failed));
				break;
			case 1:
				if (noticeTv != null) {

					noticeTv.setText((String) msg.obj);
				}
				break;
			case 205:
				View view = (View) msg.obj;
				view.setAlpha(1.0f);
				break;

			default:
				break;
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_psam);
		
		mDTMFToneEnabled = Settings.System.getInt(this.getContentResolver(),
				Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
		synchronized (mToneGeneratorLock) {
			if (mToneGenerator == null) {
				try {
					mToneGenerator = new ToneGenerator(
							AudioManager.STREAM_DTMF, TONE_RELATIVE_VOLUME);
				} catch (RuntimeException e) {
					Log.d("PSamActivity",
							"Exception caught while creating local tone generator: "
									+ e);
					mToneGenerator = null;
				}

			}
		}
		
		noticeTv = (TextView) findViewById(R.id.psam_notice_tv);
		cosEt = (EditText) findViewById(R.id.psam_cos_command_et);
		samNumSp = (Spinner) findViewById(R.id.psam_sam_num_sp);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, new String[] { 1 + "",
						2 + "", 3 + "", 4 + "", 5 + "" });
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		samNumSp.setAdapter(adapter);
		samNumSp.setSelection(4);

		psam_sam_type_sp = (Spinner) findViewById(R.id.psam_sam_type_sp);
		ArrayAdapter<String> adapter_type = new ArrayAdapter<String>(this,
				android.R.layout.simple_spinner_item, getResources()
						.getStringArray(R.array.psam_model));
		adapter_type
				.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		psam_sam_type_sp.setAdapter(adapter_type);
		psam_sam_type_sp.setSelection(0);

		psam_reset_btn = (Button)findViewById(R.id.psam_reset_btn);
		psam_change_btn = (Button)findViewById(R.id.psam_change_btn);
		
		psam_reset_btn.setOnTouchListener(btn_onTouchlistenner);
		psam_change_btn.setOnTouchListener(btn_onTouchlistenner);
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		pSamCon = PsamController.getInstance();

		try {
			pSamCon.Psam_Open(this);
			// pSamCon.resetSam(4, psam_sam_type_sp.getSelectedItemPosition());

		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		if (pSamCon != null)
			try {
				pSamCon.Psam_Close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();

	}

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.psam_execute_cos_btn:
			playTone(ToneGenerator.TONE_DTMF_1);
			String cosCommandStr = cosEt.getText().toString();
			byte[] cosMommand = parseHexStr(cosCommandStr);
			int samNum3 = Integer.parseInt((String) samNumSp.getSelectedItem()) - 1;
			if (pSamCon != null) {
				try {
					byte[] result = executeCosMommand(samNum3, cosMommand);
					if (noticeTv != null) {
						noticeTv.setText(bytesToHexString(result));
						System.out
								.println("result:" + bytesToHexString(result));
					} else {
						noticeTv.setText(getString(R.string.psam_operator_failed));
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
					noticeTv.setText("error:" + e1.getMessage());
				}
			}

			break;
		case R.id.psam_change_btn:
			playTone(ToneGenerator.TONE_DTMF_1);
			int samNum8 = Integer.parseInt((String) samNumSp.getSelectedItem()) - 1;
			if (pSamCon != null) {
				try {
					if (changeSam(samNum8)) {
						if (noticeTv != null)
							noticeTv.setText(getString(R.string.change_success));
					} else {
						if (noticeTv != null)
							noticeTv.setText(getString(R.string.change_failed));
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					noticeTv.setText("error:" + e.getMessage());
				}
			}
			break;
		case R.id.psam_reset_btn:
			playTone(ToneGenerator.TONE_DTMF_1);
			int samNum2 = Integer.parseInt((String) samNumSp.getSelectedItem()) - 1;
			if (pSamCon != null) {
				try {
					if (resetSam(samNum2,
							psam_sam_type_sp.getSelectedItemPosition())) {
						if (noticeTv != null)
							noticeTv.setText(getString(R.string.reset_success));
					} else {
						if (noticeTv != null)
							noticeTv.setText(getString(R.string.reset_failed));
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					noticeTv.setText("error:" + e.getMessage());
				}
			}
			// int samNum2 = Integer.parseInt((String)
			// samNumSp.getSelectedItem()) - 1;
			// if (pSamCon != null) {
			// try {
			// if (resetSam(samNum2)) {
			// if (noticeTv != null)
			// noticeTv.setText(getString(R.string.reset_success));
			// } else {
			// if (noticeTv != null)
			// noticeTv.setText(getString(R.string.reset_failed));
			// }
			// } catch (IOException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// noticeTv.setText("error:" + e.getMessage());
			// }
			// }
			break;

		default:
			break;
		}
	}

	private String parseRandom(byte[] result) {
		// TODO Auto-generated method stub
		if (result != null && result.length > 4) {
			if (result[4] == (byte) 0x38) {
				try {
					return bytesToHexString(result).substring(12, 20);
				} catch (IndexOutOfBoundsException e) {
					// TODO: handle exception
					e.printStackTrace();
					return getString(R.string.psam_operator_failed);
				}
			}
			return getString(R.string.psam_operator_failed);
		} else
			return getString(R.string.psam_operator_failed);
	}

	// private String parseRandom_iic(byte[] result) {
	// // TODO Auto-generated method stub
	// if (result != null && result.length > 4) {
	// try {
	// return bytesToHexString(result).substring(6, 14);
	// } catch (IndexOutOfBoundsException e) {
	// // TODO: handle exception
	// e.printStackTrace();
	// return getString(R.string.psam_operator_failed);
	// }
	//
	// } else
	// return getString(R.string.psam_operator_failed);
	// }

	private byte[] parseHexStr(String cosCommandStr) {
		// TODO Auto-generated method stub

		if (cosCommandStr != null && !cosCommandStr.trim().equals("")) {
			if (cosCommandStr.contains(",")) {
				String[] commandArr = cosCommandStr.split(",");
				byte[] command = new byte[commandArr.length];
				for (int i = 0; i < commandArr.length; i++) {
					command[i] = hexStrToByte(commandArr[i]);
				}
				return command;
			}
		}
		return null;
	}

	private byte hexStrToByte(String string) {
		// TODO Auto-generated method stub
		int value = 0;
		if (string != null) {
			switch (string.length()) {
			case 1:
				value = getValueByHexChar(string.charAt(0));
				break;
			case 2:
				value = getValueByHexChar(string.charAt(1));
				value += getValueByHexChar(string.charAt(0)) * 16;
				break;
			default:
				break;
			}
		}
		return (byte) (value & 0xFF);
	}

	private int getValueByHexChar(char charAt) {
		// TODO Auto-generated method stub
		int i = 0;
		if (charAt >= '0' && charAt <= '9') {
			i = charAt - '0';
		} else if (charAt >= 'A' && charAt <= 'F') {
			i = charAt - 'A' + 10;
		} else if (charAt >= 'a' && charAt <= 'f') {
			i = charAt - 'a' + 10;
		}
		return i;
	}

	// 字符序列转换为16进制字符串
	private String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("0x");
		if (src == null || src.length <= 0) {
			return null;
		}
		char[] buffer = new char[2];
		for (int i = 0; i < src.length; i++) {
			buffer[0] = Character.forDigit((src[i] >>> 4) & 0x0F, 16);
			buffer[1] = Character.forDigit(src[i] & 0x0F, 16);
			// System.out.println(buffer);
			stringBuilder.append(buffer);
		}
		return stringBuilder.toString();
	}

	/**
	 * 复位sam卡
	 * 
	 * @param samNum
	 *            sam卡编号 0~4
	 * @param samType
	 *            卡类型（0低速卡 1高速卡）
	 */
	public boolean resetSam(int samNum, int samType) throws IOException {
		if (pSamCon != null) {
			byte[] sourceByteArr = new byte[7];
			sourceByteArr[0] = (byte) 0xAA;// 数据长度
			sourceByteArr[1] = 0x66;
			sourceByteArr[2] = (byte) 0x00;// 数据长度 高位
			sourceByteArr[3] = (byte) 0x04;// 数据长度 低位
			sourceByteArr[4] = 0x37;// 指令码
			if (samType == 1) {
				// 高速卡38400
				sourceByteArr[5] = (byte) (((samNum & 0xFF) << 4) | (samType & 0xFF));// 要操作的psam卡代号
			} else {
				// 低速卡9600
				sourceByteArr[5] = (byte) (((samNum & 0xFF) << 4) & 0XF0);// 要操作的psam卡代号
			}
			System.out.println("sourceByteArr[5] === " + sourceByteArr[5]);
			sourceByteArr[6] = (byte) (((sourceByteArr[2] & 0xFF)
					+ (sourceByteArr[3] & 0xFF) + (sourceByteArr[4] & 0xFF) + (sourceByteArr[5] & 0xFF)) & 0xFF);// 校验位
			pSamCon.Psam_Write(sourceByteArr);

			byte[] buffer = pSamCon.Psam_Read();
			if (null != buffer && buffer.length > 0) {
				if (buffer.length >= 5) {
					if (buffer[4] == (byte) 0x37) {
						return true;
					}
				}
			}
		}
		return false;
	}

//	/**
//	 * 复位sam卡
//	 * 
//	 * @param samNum
//	 *            sam卡编号 0~4
//	 */
//	public boolean resetSam_iic(int samNum) throws IOException {
//		if (pSamCon.mOutputStream != null) {
//			byte[] sourceByteArr = new byte[4];
//			sourceByteArr[0] = (byte) 0x03;// 数据长度
//			sourceByteArr[1] = 0x37;// 指令码
//			sourceByteArr[2] = (byte) (((samNum & 0xFF) << 4) & 0XF0);// 要操作的psam卡代号
//			sourceByteArr[3] = (byte) ((sourceByteArr[0] & 0xFF)
//					^ (sourceByteArr[1] & 0xFF) ^ (sourceByteArr[2] & 0xFF));// 校验位
//			// pSamCon.mOutputStream.write(sourceByteArr);
//			// pSamCon.mOutputStream.flush();
//			pSamCon.Psam_Write(sourceByteArr);
//			byte[] buffer = pSamCon.Psam_Read();
//			// byte[] buffer = new byte[1024];
//			// int ret = pSamCon.mInputStream.read(buffer);
//			// if (ret > 0) {
//			for (int i = 0; i < buffer.length; i++) {
//				if (buffer[i] == (byte) 0x37) {
//					return true;
//				}
//			}
//			// }
//
//		}
//		return false;
//	}

	/**
	 * 切换成高速卡
	 * 
	 * @param samNum
	 *            sam卡编号 0~4
	 */
	public boolean changeSam(int samNum) throws IOException {
		if (pSamCon != null) {
			byte[] sourceByteArr = new byte[9];
			sourceByteArr[0] = (byte) 0xAA;// 数据长度
			sourceByteArr[1] = 0x66;
			sourceByteArr[2] = (byte) 0x00;// 数据长度 高位
			sourceByteArr[3] = (byte) 0x06;// 数据长度 低位
			sourceByteArr[4] = 0x37;// 指令码
			// sourceByteArr[5] = (byte) (((samNum & 0xFF) << 4) | (2 &
			// 0xFF));// 要操作的psam卡代号
			// sourceByteArr[5] = (byte) 0x48;// 要操作的psam卡代号
			sourceByteArr[5] = (byte) (((samNum & 0xFF) << 4) | 0x0c);
			;// 要操作的psam卡代号
			sourceByteArr[6] = (byte) 0x10;
			sourceByteArr[7] = (byte) 0x13;

			sourceByteArr[8] = (byte) (((sourceByteArr[2] & 0xFF)
					+ (sourceByteArr[3] & 0xFF) + (sourceByteArr[4] & 0xFF)
					+ (sourceByteArr[5] & 0xFF) + (sourceByteArr[6] & 0xFF) + (sourceByteArr[7] & 0xFF)) & 0xFF);// 校验位
			pSamCon.Psam_Write(sourceByteArr);

			// byte[] buffer = null;
			// try {
			// Thread.sleep(500);
			// } catch (InterruptedException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
			// int count = mInputStream.available();
			// if (count > 0) {
			// buffer = new byte[count];
			// mInputStream.read(buffer);
			// Log.i("changeSam", Tools.bytesToHexString(buffer));
			// }

			byte[] buffer = pSamCon.Psam_Read();
			if (null != buffer && buffer.length > 0) {
				if (buffer.length >= 5) {
					if (buffer[4] == (byte) 0x37) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * 修改sam卡工作频率
	 * 
	 * @param hz
	 *            工作频率
	 */
	public boolean setSamHz(int hz) throws IOException {
		System.out.println("修改sam卡工作频率" + hz);
		if (pSamCon != null) {
			byte[] sourceByteArr = new byte[7];
			sourceByteArr[0] = (byte) 0xAA;// 数据长度
			sourceByteArr[1] = 0x66;
			sourceByteArr[2] = (byte) 0x00;// 数据长度 高位
			sourceByteArr[3] = (byte) 0x04;// 数据长度
			sourceByteArr[4] = 0x36;// 指令码
			sourceByteArr[5] = (byte) (hz & 0xFF);// 要操作的psam卡功率
			sourceByteArr[6] = (byte) (((sourceByteArr[2] & 0xFF)
					+ (sourceByteArr[3] & 0xFF) + (sourceByteArr[4] & 0xFF) + (sourceByteArr[5] & 0xFF)) & 0xFF);// 校验位
			// sourceByteArr[0] = (byte) 0x03;// 数据长度
			// sourceByteArr[1] = 0x36;// 指令码
			// sourceByteArr[2] = (byte) (hz & 0xFF);// 要操作的psam卡代号
			// sourceByteArr[6] = (byte) ((sourceByteArr[0] & 0xFF)
			// ^ (sourceByteArr[1] & 0xFF) ^ (sourceByteArr[2] & 0xFF));// 校验位
			pSamCon.Psam_Write(sourceByteArr);

			byte[] buffer = pSamCon.Psam_Read();
			if (null != buffer && buffer.length > 0) {
				if (buffer.length >= 5) {
					if (buffer[4] == (byte) 0x36) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * 执行cos命令
	 * 
	 * @param samNum
	 *            要操作哪张sam卡
	 * @param cosMommand
	 *            cos命令
	 */
	public byte[] executeCosMommand(int samNum, byte[] cosMommand)
			throws IOException {
		byte[] result = null;
		if (pSamCon != null && cosMommand != null) {
			byte[] sourceByteArr = new byte[7 + cosMommand.length];
			sourceByteArr[0] = (byte) 0xAA;// 数据长度
			sourceByteArr[1] = 0x66;
			sourceByteArr[2] = (byte) 0x00;// 数据长度 高位
			sourceByteArr[3] = (byte) (sourceByteArr.length - 3);// 长度 地位
			sourceByteArr[4] = 0x38;// 指令码
			sourceByteArr[5] = (byte) (samNum & 0xFF);// 要操作的卡代号
			// sourceByteArr[0] = (byte) (sourceByteArr.length - 1);// 长度
			// sourceByteArr[1] = 0x38;// 指令码
			// sourceByteArr[2] = (byte) (samNum & 0xFF);// 要操作的卡代号

			// 填充cos指令
			for (int i = 0; i < cosMommand.length; i++) {
				sourceByteArr[i + 6] = cosMommand[i];
			}
			// sourceByteArr[sourceByteArr.length - 2] = 0x00;// 这一位默认为0

			// 算校验
			for (int i = 2; i < sourceByteArr.length - 1; i++) {
				sourceByteArr[sourceByteArr.length - 1] = (byte) (((sourceByteArr[sourceByteArr.length - 1] & 0xFF) + (sourceByteArr[i] & 0xFF)) & 0xFF);
			}
			pSamCon.Psam_Write(sourceByteArr);

			byte[] buffer = pSamCon.Psam_Read();
			if (null != buffer && buffer.length > 0) {
				return buffer;
			}
		}
		return result;
	}

//	/**
//	 * 执行cos命令
//	 * 
//	 * @param samNum
//	 *            要操作哪张sam卡
//	 * @param cosMommand
//	 *            cos命令
//	 */
//	public byte[] executeCosMommand_iic(int samNum, byte[] cosMommand)
//			throws IOException {
//		byte[] result = null;
//		if (pSamCon != null && cosMommand != null) {
//			byte[] sourceByteArr = new byte[5 + cosMommand.length];
//			sourceByteArr[0] = (byte) (sourceByteArr.length - 1);// 长度
//			sourceByteArr[1] = 0x38;// 指令码
//			sourceByteArr[2] = (byte) (samNum & 0xFF);// 要操作的卡代号
//
//			// 填充cos指令
//			for (int i = 0; i < cosMommand.length; i++) {
//				sourceByteArr[i + 3] = cosMommand[i];
//			}
//			sourceByteArr[sourceByteArr.length - 2] = 0x00;// 这一位默认为0
//
//			// 算校验
//			for (int i = 0; i < sourceByteArr.length - 1; i++) {
//				sourceByteArr[sourceByteArr.length - 1] = (byte) ((sourceByteArr[sourceByteArr.length - 1] & 0xFF) ^ (sourceByteArr[i] & 0xFF));
//			}
//			// pSamCon.mOutputStream.write(sourceByteArr);
//			// pSamCon.mOutputStream.flush();
//			// byte[] buffer = new byte[1024];
//			// int ret = pSamCon.mInputStream.read(buffer);
//			pSamCon.Psam_Write(sourceByteArr);
//			byte[] buffer = pSamCon.Psam_Read();
//			if (null != buffer && buffer.length > 0) {
//				return buffer;
//			}
//		}
//		return result;
//	}

	/**
	 * 检测MF文件是否存在
	 * 
	 * @param samNum
	 *            要操作的卡槽
	 * @return 1:存在 0:不存在 -1:无返回
	 * @throws IOException
	 */
	public int executeFileExits(int samNum) throws IOException {
		byte[] result = executeCosMommand(samNum, fileExitsCom);
		if (result != null && result.length >= 7 && result[4] == (byte) 0x38) {
			if (result[5] == (byte) 0x6a && result[6] == (byte) 0x81) {
				Log.i("info", "没有mf文件");
				return 0;
			} else if (result[5] == (byte) 0x61) {
				return 1;
			} else if (result[5] == (byte) 0x90 && result[6] == (byte) 0x00) {
				return 1;
			}
			return -1;
			// if (result.length >= 3 && result[1] == (byte) 0x38
			// && result[2] == -112) {
			// return 1;
			// } else {
			// return 0;
			// }
		} else {
			return -1;
		}
	}

	/**
	 * 创建MF文件
	 * 
	 * @param samNum
	 *            要操作的卡槽
	 * @return
	 * @throws IOException
	 */
	public byte[] executeCreateFile(int samNum) throws IOException {
		return executeCosMommand(samNum, createFileCom);
	}

	/**
	 * 生成随机数
	 * 
	 * @param samNum
	 *            要操作的卡槽
	 * @return
	 * @throws IOException
	 */
	public byte[] executeCreateRandom(int samNum) throws IOException {
		return executeCosMommand(samNum, createRandomCom);
	}
	
	private void playTone(int tone) {
		if (!mDTMFToneEnabled) {
			return;
		}
		AudioManager audioManager = (AudioManager) PSamActivity.this
				.getSystemService(Context.AUDIO_SERVICE);
		int ringerMode = audioManager.getRingerMode();
		if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
				|| (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
			return;
		}

		synchronized (mToneGeneratorLock) {
			if (mToneGenerator == null) {
				Log.d("PSamActivity", "playTone: mToneGenerator == null, tone: " + tone);
				return;
			}
			mToneGenerator.startTone(tone, TONE_LENGTH_MS);
		}
	}
	
	Button.OnTouchListener btn_onTouchlistenner = new Button.OnTouchListener() {
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_DOWN) {
				v.setAlpha(0.5f);
				Message message = new Message();
				message.what = 205;
				message.obj = v;
				mHandler.sendMessageDelayed(message, 500);
				Log.i("TestAndroid Button", "MotionEvent.ACTION_DOWN");
			} else if (event.getAction() == MotionEvent.ACTION_UP) {
				v.setAlpha(1.0f);
				Log.i("TestAndroid Button", "MotionEvent.ACTION_UP");
			}
			return false;
		}
	};
}
